package com.xyoto.community.service.impl;

import com.xyoto.community.cache.CacheInstruction;
import com.xyoto.community.mapper.picture.DynamicPictureMapper;
import com.xyoto.community.po.DynamicPicturePO;
import com.xyoto.community.service.PictureCacheService;
import com.xyoto.community.utils.RedisCommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * @author coderFu
 * @create 2021/12/5
 */
@Service
@Slf4j
public class PictureCacheServiceImpl implements PictureCacheService {

    @Autowired
    private RedisCommonUtils redisCommonUtils;

    @Autowired
    private DynamicPictureMapper dynamicPictureMapper;

    private final Random random = new Random();


    @Override
    @Async("taskExecutor")
    public void addPictureToCache(Integer pictureId, String path) {
        //添加到缓存中
        redisCommonUtils.hset(CacheInstruction.DYNAMIC_PICTURE,
                pictureId, path,
                CacheInstruction.DYNAMIC_PICTURE_EXPIRE_TIME + random.nextInt((int) (CacheInstruction.DYNAMIC_PICTURE_EXPIRE_TIME * 0.05)));
    }

    @Override
    @Async("taskExecutor")
    public void deletePictureFromCache(Integer pictureId) {
        //判断是否在缓存中
        boolean flag = redisCommonUtils.judgeHashExistKey(CacheInstruction.DYNAMIC_PICTURE, pictureId);
        if (flag) {
            redisCommonUtils.hdel(CacheInstruction.DYNAMIC_PICTURE, pictureId);
        }
    }

    @Override
    public String getPicturePathFromCache(Integer pictureId) {
        //查询缓存中是否存在
        boolean flag = redisCommonUtils.judgeHashExistKey(CacheInstruction.DYNAMIC_PICTURE, pictureId);
        Object path = null;
        path = redisCommonUtils.hget(CacheInstruction.DYNAMIC_PICTURE, pictureId);
        if (flag) {
            return path.toString();
        } else {
            //查询数据库
            path = dynamicPictureMapper.getDynamicPicturePathFromDB(pictureId);
            //存储到缓存中
            redisCommonUtils.hset(CacheInstruction.DYNAMIC_PICTURE,
                    pictureId, path,
                    CacheInstruction.DYNAMIC_PICTURE_EXPIRE_TIME + random.nextInt((int) (CacheInstruction.DYNAMIC_PICTURE_EXPIRE_TIME * 0.05)));
        }
        return path.toString();
    }

    @Override
    public List<Integer> getPictureIdsFromCache(Integer dynamicId) {
        //判断缓存中是否存在
        String key = CacheInstruction.DYNAMIC_PICTURE_ID + dynamicId;
        Boolean flag = redisCommonUtils.hasKey(key);
        //存储动态图片id的容器
        List<Integer> dynamicPictureIds = new ArrayList<>();
        if (flag) {
            //从缓存中取出动态图片id
            List<Object> objects = (List<Object>) redisCommonUtils.lGetIndex(key,0);
            if (objects.size() > 0) {
                dynamicPictureIds = objects.stream().map(id->Integer.valueOf(id.toString())).collect(Collectors.toList());
            }
        } else {
            //从数据库中取出图片信息
            log.info("查询动态图片的动态id为"+dynamicId);
            dynamicPictureIds = dynamicPictureMapper.getDynamicPictureIdListFromDB(dynamicId);
            redisCommonUtils.lSet(key, dynamicPictureIds,
                    CacheInstruction.DYNAMIC_PICTURE_ID_EXPIRE_TIME + random.nextInt((int) (CacheInstruction.DYNAMIC_PICTURE_EXPIRE_TIME * 0.05)));
        }
        return dynamicPictureIds;
    }

    @Override
    @Async("taskExecutor")
    public void deletePictureIdsFromCache(Integer dynamicId) {
        String key = CacheInstruction.DYNAMIC_PICTURE_ID+dynamicId;
        //判断缓存是否存在
        Boolean flag = redisCommonUtils.hasKey(key);
        if (flag){
            //取出缓存的值
            List<Object> objects = redisCommonUtils.lGet(key, 0, -1);
            if (objects.size() != 0){
                objects.forEach(id->{
                    deletePictureFromCache(Integer.valueOf(id.toString()));
                });
            }
        }else {
            //查询DB
            List<Integer> dynamicPictureIds = dynamicPictureMapper.getDynamicPictureIdListFromDB(dynamicId);
            //删除缓存中存储到图片信息
            if (dynamicPictureIds.size() != 0){
                for (Integer pictureId : dynamicPictureIds) {
                    deletePictureFromCache(pictureId);
                }
            }
        }
    }

    @Override
    public List<DynamicPicturePO> getDynamicPicturePoFromCache(Integer dynamicId) {
        //从缓存中获取图片id集合
        List<Integer> pictureIds = getPictureIdsFromCache(dynamicId);
        if (pictureIds.size() == 0){
            return new ArrayList<>();
        }
        List<DynamicPicturePO> dynamicPicturePoList = new ArrayList<>();
        for (Integer pictureId : pictureIds) {
            DynamicPicturePO dynamicPicturePo = new DynamicPicturePO();
            dynamicPicturePo.setId(pictureId);
            dynamicPicturePo.setKeyId(dynamicId);
            dynamicPicturePo.setPath(getPicturePathFromCache(pictureId));
            dynamicPicturePoList.add(dynamicPicturePo);
        }
        return dynamicPicturePoList;
    }
}

